package com.gun3y.utils;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.htmlcleaner.BelongsTo;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.SimpleHtmlSerializer;
import org.htmlcleaner.TagNode;

public class UrlUtil {

    private static final String[] ATTRIBUTES = { "href", "src", "link", "url" };

    private UrlUtil() {
	super();
    }

    public static String cleanHtml(String html, String charset, String url) {
	String res = StringUtils.EMPTY;
	if (StringUtils.isNotBlank(html)) {
	    CleanerProperties props = new CleanerProperties();

	    props.setTranslateSpecialEntities(true);

	    props.setOmitComments(true);

	    HtmlCleaner htmlCleaner = new HtmlCleaner(props);

	    htmlCleaner.getTagInfoProvider().getTagInfo("meta").setBelongsTo(BelongsTo.HEAD_AND_BODY);
	    TagNode nodes = htmlCleaner.clean(html);
	    for (String attName : ATTRIBUTES) {
		normalizeUrls(nodes, attName, url);
	    }

	    SimpleHtmlSerializer htmlSerializer = new SimpleHtmlSerializer(props);
	    res = htmlSerializer.getAsString(nodes, charset);
	}
	return res;
    }

    private static void normalizeUrls(TagNode nodes, String attName, String url) {
	List<?> nodeList = nodes.getElementListHavingAttribute(attName, true);
	for (Object obj : nodeList) {
	    if (obj instanceof TagNode) {
		TagNode tagNone = (TagNode) obj;
		String param = tagNone.getAttributeByName(attName);

		if (StringUtils.isNotBlank(param)
			&& !(param.startsWith("http") || param.startsWith("//") || param.startsWith("javascript:") || param.charAt(0) == '#')) {
		    tagNone.getAttributes().put(attName, createFullPath(url, param));
		}
	    }
	}
    }

    /**
     * Some values in result fields should be concatenate with SE cover URL.
     * This method determines whether given field needs that.
     * 
     * @param param
     * @param paramValue
     * @return
     */
    public static boolean needURLOperation(String param, String paramValue) {
	if (StringUtils.isNotBlank(param) && StringUtils.isNotBlank(paramValue)) {
	    param = param.toLowerCase();
	    paramValue = paramValue.trim();
	    for (String attName : ATTRIBUTES) {
		if (param.contains(attName) && !checkUrl(paramValue)) {
		    return true;
		}
	    }
	}

	return false;
    }

    public static boolean checkUrl(String param) {
	if (StringUtils.isBlank(param)) {
	    return false;
	}

	if (param.startsWith("http") || param.startsWith("www") || param.startsWith("//") || param.startsWith("javascript:")
		|| param.charAt(0) == '#') {
	    return true;
	}

	return false;
    }

    /**
     * Given result field value is appended to SE cover URL since this field is
     * a link or file
     * 
     * @param baseUrl
     * @param relUrl
     * @return
     */
    public static String createFullPath(String baseUrl, String relUrl) {
	String retVal = "";
	String bUrl = baseUrl;
	String rUrl = relUrl;

	if (StringUtils.isBlank(bUrl) || StringUtils.isBlank(rUrl)) {
	    return retVal;
	}

	if (!bUrl.startsWith("http")) {
	    bUrl = "http://" + bUrl;
	}

	if (bUrl.endsWith("/")) {
	    if (rUrl.charAt(0) == '/') {
		rUrl = rUrl.substring(1);
		retVal = bUrl + rUrl;
	    }
	    else {
		retVal = bUrl + rUrl;
	    }
	}
	else if (rUrl.charAt(0) == '/') {
	    retVal = bUrl + rUrl;
	}
	else {
	    retVal = bUrl + "/" + rUrl;
	}
	return retVal;
    }

    public static String concatParam(String baseUrl, String parameter) {
	String retValue = "";

	if (StringUtils.isBlank(baseUrl)) {
	    return retValue;
	}
	if (StringUtils.isBlank(parameter)) {
	    return baseUrl;
	}
	String param = parameter;
	if (param.charAt(0) == '?' || param.charAt(0) == '&') {
	    param = param.substring(1);
	}

	if (baseUrl.contains("?")) {
	    if (baseUrl.endsWith("&")) {
		retValue = baseUrl + param;
	    }
	    else {
		retValue = baseUrl + "&" + param;
	    }
	}
	else {
	    retValue = baseUrl + "?" + param;
	}
	return retValue;
    }

}
